/*!
 * @file        apm32f0xx_crs.h
 *
 * @brief       This file contains all the functions prototypes for the CRS firmware library
 *
 * @note        It's only for APM32F072 and APM32F091 devices
 *
 * @version     V1.0.1
 *
 * @date        2021-07-01
 *
 */

#ifndef __CRS_H
#define __CRS_H

#include "apm32f0xx.h"

#ifdef __cplusplus
extern "C" {
#endif

/** @addtogroup Peripherals_Library Standard Peripheral Library
  @{
*/

/** @addtogroup CRS_Driver CRS Driver
  @{
*/

/** @addtogroup CRS_Enumerations Enumerations
  @{
*/

/**
 * @brief    CRS_Interrupt_Sources
 */
typedef enum
{                                                       
    CRS_INT_SYNCOK    =  ((uint32_t)0x00000001), //!<SYNC event OK interrupt
    CRS_INT_SYNCWARN  =  ((uint32_t)0x00000002), //!<SYNC warning interrupt
    CRS_INT_ERR       =  ((uint32_t)0x00000004), //!<Synchronization or trimming error interrupt
    CRS_INT_ESYNC     =  ((uint32_t)0x00000008), //!<Expected SYNC interrupt
    CRS_INT_SYNCERR   =  ((uint32_t)0x00000100), //!<SYNC error
    CRS_INT_SYNCMISS  =  ((uint32_t)0x00000200), //!<SYNC missed
    CRS_INT_TRIMOVF   =  ((uint32_t)0x00000400), //!<Trimming overflow or underflow                                                      
}CRS_INT_T;

/**
 * @brief    CRS_Flags
 */
typedef enum
{
     CRS_FLAG_SYNCOK    =  ((uint32_t)0x00000001), //!<SYNC event OK flag
     CRS_FLAG_SYNCWARN  =  ((uint32_t)0x00000002), //!<SYNC warning flag
     CRS_FLAG_ERR       =  ((uint32_t)0x00000004), //!<Synchronization or trimming error flag
     CRS_FLAG_ESYNC     =  ((uint32_t)0x00000008), //!<Expected SYNC flag
     CRS_FLAG_SYNCERR   =  ((uint32_t)0x00000100), //!<SYNC error flag
     CRS_FLAG_SYNCMISS  =  ((uint32_t)0x00000200), //!<SYNC missed flag
     CRS_FLAG_TRIMOVF   =  ((uint32_t)0x00000400), //!<Trimming overflow or underflow falg
}CRS_FLAG_T;

/**
 * @brief    CRS_Synchro_Source
 */
typedef enum
{
    CRS_SYNC_SOURCE_GPIO =  0x00, //!<GPIO selected as SYNC signal source
    CRS_SYNC_SOURCE_LSE  =  0x01, //!<LSE selected as SYNC signal source
    CRS_SYNC_SOURCE_USB  =  0x02, //!<USB SNFLG selected as SYNC signal source (default).
}CRS_SYNC_SOURCE_T;

/**
 * @brief    CRS_Synchro_Source
 */
typedef enum
{
    CRS_SYNC_DIV1   =  0x00, //!<Synchro Signal not divided (default)
    CRS_SYNC_DIV2   =  0x01, //!<Synchro Signal divided by 2
    CRS_SYNC_DIV4   =  0x02, //!<Synchro Signal divided by 4
    CRS_SYNC_DIV8   =  0x03, //!<Synchro Signal divided by 8
    CRS_SYNC_DIV16  =  0x04, //!<Synchro Signal divided by 16
    CRS_SYNC_DIV32  =  0x05, //!<Synchro Signal divided by 32
    CRS_SYNC_DIV64  =  0x06, //!<Synchro Signal divided by 64
    CRS_SYNC_DIV128 =  0x07, //!<Synchro Signal divided by 128
} CRS_SYNC_DIV_T;

/**@} end of group CRS_Enumerations*/


/** @addtogroup CRS_Structure Data Structure
  @{
*/

/**
 * @brief    CRS_SynchroPolarity
 */
typedef enum
{
    CRS_SYNC_POL_RISING, //!<Synchro active on rising edge
    CRS_SYNC_POL_FALLING //!<Synchro active on falling edge
}CRS_SYNC_POL_T;

/**@} end of group CRS_Structure*/


/** @addtogroup CRS_Fuctions Fuctions
  @{
*/

/** Configuration of the CRS **/
void CRS_Reset(void);
void CRS_AdjustHSI48CalibrationValue(uint8_t calibrationVal);
void CRS_EnableFrequencyErrorCounter(void);
void CRS_DisableFrequencyErrorCounter(void);
void CRS_EnableAutomaticCalibration(void);
void CRS_DisableAutomaticCalibration(void);
void CRS_GenerateSoftwareSynchronization(void);
void CRS_FrequencyErrorCounterReloadValue(uint16_t reloadVal);
void CRS_ConfigFrequencyErrorLimit(uint8_t errLimitVal);
void CRS_ConfigSynchronizationPrescaler(CRS_SYNC_DIV_T div);
void CRS_ConfigSynchronizationSource(CRS_SYNC_SOURCE_T source);
void CRS_ConfigSynchronizationPolarity(CRS_SYNC_POL_T polarity);
uint32_t CRS_ReadReloadValue(void);
uint32_t CRS_ReadHSI48CalibrationValue(void);
uint32_t CRS_ReadFrequencyErrorValue(void);
uint32_t CRS_ReadFrequencyErrorDirection(void);

/** Interrupts and flags management functions **/
void CRS_EnableInterrupt(CRS_INT_T interrupt);
void CRS_DisableInterrupt(CRS_INT_T interrupt);
uint8_t CRS_ReadStatusFlag(CRS_FLAG_T flag);
void CRS_ClearStatusFlag(CRS_FLAG_T flag);
uint8_t CRS_ReadIntFlag(CRS_INT_T flag);
void CRS_ClearIntFlag(CRS_INT_T intFlag);

/**@} end of group CRS_Fuctions*/
/**@} end of group CRS_Driver */
/**@} end of group Peripherals_Library*/

#ifdef __cplusplus
}
#endif

#endif /* __CRS_H */
